package com.easytouch.vmhdl.presenter;

import android.annotation.SuppressLint;
import android.os.AsyncTask;

import com.easytouch.core.Configure;
import com.easytouch.core.encryption.MD5;
import com.easytouch.core.utils.Log;
import com.easytouch.vmhdl.interfaces.ILoginView;
import com.easytouch.vmhdl.model.ILoginModel;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * Created by gulin on 2018/1/5.
 */

public class LoginPresenter {

    private ILoginView mLoginView;
    private ILoginModel mLoginModel;
    private Log mLogger = new Log("LoginPresenter.txt");
    private static boolean isFirstLogin = true;
    private String mStrPassword = "";

    public LoginPresenter(ILoginView pView, ILoginModel pModel)
    {
        mLoginView = pView;
        mLoginModel = pModel;
    }

    public void addPasswordChar(final int pNumber)
    {
        String content = mStrPassword;
        if(content.length() > 16)
        {
            return;
        }
        content += String.valueOf(pNumber);
        mStrPassword = content;
        int len = content.length();
        content = "";
        for (int i = 0; i < len;i++)
        {
            content += "*";
        }
        mLoginView.setPasswordText(content);
    }

    public void onClearPassword()
    {
        mStrPassword = "";
        mLoginView.setPasswordText("");
    }

    @SuppressLint("StaticFieldLeak")
    public void onLogin(final String pUsername)
    {
//        boolean isSuccess = true;
//        if (isSuccess) //dummy代码，为了方便测试
//        {
//            mLoginView.showMessage(ILoginView.LOGIN_SUCCESS);
//            return;
//        }
        String pPassword = mStrPassword;
        if(pUsername == null || "".equals(pUsername))
        {
            mLoginView.showMessage(ILoginView.LOGIN_NO_USERNAME);
            return;
        }
        if(pPassword == null || "".equals(pPassword))
        {
            mLoginView.showMessage(ILoginView.LOGIN_NO_PASSWORD);
            return;
        }
        //网络验证
        new AsyncTask<String, Void, Integer>()
        {
            @Override
            protected void onPreExecute()
            {
                mLoginView.showProgressBar();
            }

            @Override
            protected Integer doInBackground(String... params) {
                String name = params[0];
                String pass = params[1];
                String ip = "easytouch-pay.cn";
                int port = 6001;
                Socket socket = null;
                SocketAddress address = new InetSocketAddress(ip, port);
                OutputStream out = null;
                InputStream in = null;

                boolean isConnectOK = false;
                int retry = 3;
                while (!isConnectOK) {
                    try {
                        isConnectOK = true;
                        socket = new Socket();
                        socket.connect(address, 15000);
                        socket.setSoTimeout(20000);
                        socket.setKeepAlive(true);
                    } catch (IOException e) {
                        isConnectOK = false;
                        retry--;
                        if (retry <= 0) {
                            mLogger.i("retry connect 3 times failed. cause is : " + e.getMessage() + ", " + e.getCause());
                            if (socket != null) {
                                try {
                                    socket.close();
                                } catch (IOException e1) {
                                }
                            }
                            return check(name, pass);
                        }
                    }
                }

                try {
                    out = socket.getOutputStream();
                    in = socket.getInputStream();
                    byte[] buffer = new byte[1024 * 8];
                    if (isFirstLogin) //第一次登陆
                    {
                        isFirstLogin = false;
                        //下载数据
                        // 请求内容：协议头（两位 82）+机器号（8位）
                        out.write(("82" + Configure.getMacNo()).getBytes("UTF-8"));
                        // 应答内容：报文长度（不包括本身）+多个验证码（以_分隔的多个md5验证码组成，验证码是用户名+密码组合的md5码）
                        int len = in.read(buffer);
                        String infos = new String(buffer, 0, len); // 报文长度（不包括本身）+多个验证码（以_分隔的多个md5验证码组成，验证码是用户名+密码组合的md5码）
                        mLogger.i("first login :" + infos);
                        mLoginModel.setEncryptLoginInfo(infos);
                        int checkResult = check(name, pass);
                        if(checkResult == ILoginView.LOGIN_SUCCESS)
                        {
                            return checkResult;
                        }
                    }
                    //直接验证用户名和密码
                    // 请求内容：协议头（两位 81）+机器号（8位）+ 验证码（固定md5字符串 32位小写）
                    out.write(("81" + Configure.getMacNo() + MD5.md5Encode(name + pass)).getBytes("UTF-8"));
                    // 应答内容：报文长度2位（不包括本身）+机器号（8位）+验证码（1位，0表示验证失败，1表示验证成功）
                    int len = in.read(buffer);
                    String info = new String(buffer, 0, len);
                    mLogger.i("not first login :" + info);
                    if(info == null || info.length() < 11)
                    {
                        return ILoginView.LOGIN_NET_ERROR;
                    }
                    if(info.charAt(10) == '1')
                    {
                        return ILoginView.LOGIN_SUCCESS;
                    }
                    else
                    {
                        return ILoginView.LOGIN_FAILED;
                    }
                } catch (IOException e)
                {
                    mLogger.e("send data error:" + e.getMessage());
                    return check(name, pass);
                }
                finally {
                    try {
                        if(in != null)
                            in.close();
                        if(out != null)
                            out.close();
                        if(socket != null)
                            socket.close();
                    } catch (IOException e)
                    {

                    }
                }
            }

            @Override
            protected void onPostExecute(Integer result)
            {
                mLoginView.hideProgressBar();
                mLoginView.showMessage(result);
                super.onPostExecute(result);
            }
        }.execute(pUsername, pPassword);
    }

    private int check(final String pUsername, final String pPassword)
    {
        String info = mLoginModel.getEncryptLoginInfo();
        if(info == null || "".equals(info))
        {
            return ILoginView.LOGIN_NET_ERROR;
        }
        String md5 = MD5.md5Encode(pUsername + pPassword);
        if(info.contains(md5))
        {
            return ILoginView.LOGIN_SUCCESS;
        }
        else
        {
            return ILoginView.LOGIN_FAILED;
        }
    }
}
